/*{
"CATEGORIES": [
"Color Effect"
],
"CREDIT": "by VIDVOX",
"DESCRIPTION": "Creates variations on a base color using a given algorithm.",
"INPUTS": [
{
"NAME": "inputImage",
"TYPE": "image"
},
{
"DEFAULT": 0,
"LABEL": "Sample Mode",
"LABELS": [
"Base Color",
"Pixel Follow",
"Color Average"
],
"NAME": "sampleMode",
"TYPE": "long",
"VALUES": [
0,
1,
2
]
},
{
"DEFAULT": 1,
"LABEL": "Color Mode",
"LABELS": [
"Basic Complementary",
"Split Complementary",
"Compound Complementary",
"Spectrum",
"Shades",
"Analogous",
"Compound Analogous"
],
"NAME": "colorModeOverride",
"TYPE": "long",
"VALUES": [
0,
1,
2,
3,
4,
5,
6
]
},
{
"DEFAULT": 7,
"LABEL": "Color Count",
"LABELS": [
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"11",
"12",
"13",
"14",
"15",
"16"
],
"NAME": "colorCount",
"TYPE": "long",
"VALUES": [
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16
]
},
{
"DEFAULT": [
0.25,
0.59,
0.9,
1
],
"LABEL": "Base Color",
"NAME": "baseColor",
"TYPE": "color"
},
{
"DEFAULT": [
0.5,
0.5
],
"LABEL": "Pixel Point",
"MAX": [
1,
1
],
"MIN": [
0,
0
],
"NAME": "pixelFollowLocation",
"TYPE": "point2D"
}
],
"ISFVSN": "2",
"PASSES": [
{
"HEIGHT": "$HEIGHT / 100.0",
"TARGET": "bufferPassA",
"WIDTH": "$WIDTH / 100.0"
},
{
"HEIGHT": "1.0",
"TARGET": "autoColorBuffer",
"WIDTH": "1.0",
"persistent": true
},
{
}
]
}
*/
vec3 rgb2hsv(vec3 c) {
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
//vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
//vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy);
vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx);
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
vec3 hsv2rgb(vec3 c) {
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
float gray(vec4 c) {
return (c.r + c.g + c.b) * c.a / 3.0;
}
void main()
{
if (PASSINDEX == 0) {
vec4 inputColor = IMG_NORM_PIXEL(inputImage, isf_FragNormCoord);
gl_FragColor = inputColor;
}
else if (PASSINDEX == 1) {
vec4 inputColor = IMG_NORM_PIXEL(bufferPassA, isf_FragNormCoord);
vec4 oldColor = IMG_NORM_PIXEL(autoColorBuffer, vec2(0.5,0.5));
gl_FragColor = mix(inputColor, oldColor, 0.8);
}
else if (PASSINDEX == 2) {
vec4 inputColor = IMG_THIS_PIXEL(inputImage);
vec4 inColor = baseColor;
float index = floor(gray(inputColor) * float(colorCount));
//float index = floor(isf_FragNormCoord.x * float(colorCount));
float variation = 0.3236; // 1/5 the golden ratio
int colorMode = colorModeOverride;
if (sampleMode == 0) {
inColor = baseColor;
inColor.rgb = rgb2hsv(inColor.rgb);
}
else if (sampleMode == 1) {
inColor = IMG_NORM_PIXEL(inputImage, pixelFollowLocation);
inColor.rgb = rgb2hsv(inColor.rgb);
}
else if (sampleMode == 2) {
inColor = IMG_NORM_PIXEL(autoColorBuffer, vec2(0.5,0.5));
inColor.rgb = rgb2hsv(inColor.rgb);
if (inColor.b < 0.1) {
inColor = inColor * 1.5;
}
}
vec4 outColor = inColor;
// Basic complimentary saturation and brightness variations on two fixed 180 degree opposite hues
if (colorMode == 0) {
if (mod(index, 2.0) >= 1.0) {
outColor.r = outColor.r + 0.5;
outColor.r = outColor.r - floor(outColor.r);
}
outColor.g = outColor.g - variation * floor(index / 2.0);
if (outColor.g < 0.1) {
outColor.g = outColor.g + variation * floor(index / 2.0);
outColor.g = outColor.g - floor(outColor.g);
}
outColor.b = outColor.b - variation * floor(index / 4.0);
if (outColor.b < 0.2) {
outColor.b = outColor.b + variation * floor(index / 4.0);
outColor.b = outColor.b - floor(outColor.b);
}
}
// Split complimentary saturation and brightness variations on a 3 fixed 120 degree hues
else if (colorMode == 1) {
float divisor = 3.0;
float ratio = 0.45;
if (mod(index, 3.0) >= 2.0) {
outColor.r = outColor.r - ratio;
}
else if (mod(index, 3.0) >= 1.0) {
outColor.r = outColor.r + ratio;
}
//outColor.g = outColor.g + variation * floor(index / divisor);
if (mod(index, 5.0) >= 3.0) {
outColor.g = outColor.g - variation;
outColor.g = outColor.g - floor(outColor.g);
}
outColor.b = outColor.b - variation * floor(index / (divisor));
if (outColor.b < 0.1) {
outColor.b = outColor.b + variation * floor(index / (divisor));
outColor.b = outColor.b - floor(outColor.b);
}
}
// Compound complimentary a combination of shades, complimentary and analogous colors with slight shifts
else if (colorMode == 2) {
if (mod(index, 3.0) >= 2.0) {
outColor.r = outColor.r + 0.5;
outColor.r = outColor.r + variation * index * 1.0 / float(colorCount - 1) / 4.0;
}
else {
outColor.r = outColor.r + variation * index * 1.0 / float(colorCount - 1);
}
outColor.r = outColor.r - floor(outColor.r);
if (mod(index, 2.0) >= 1.0) {
outColor.g = outColor.g + index * variation / 2.0;
}
else if (mod(index, 3.0) >= 2.0) {
outColor.g = outColor.g - variation / 2.0;
}
else {
outColor.g = outColor.g - index * variation / float(colorCount - 1);
}
if (outColor.g > 1.0) {
outColor.g = outColor.g - floor(outColor.g);
}
}
// Spectrum hue shifts based on number of colors with minor saturation shifts
else if (colorMode == 3) {
outColor.r = outColor.r + index * 1.0 / float(colorCount);
if (mod(index, 3.0) >= 2.0) {
outColor.g = outColor.g - variation / 2.0;
outColor.g = outColor.g - floor(outColor.g);
}
else if (mod(index, 4.0) >= 3.0) {
outColor.g = outColor.g + variation / 2.0;
//outColor.g = outColor.g - floor(outColor.g);
}
}
// Shades saturation and brightness variations on a single fixed hue
else if (colorMode == 4) {
if (mod(index, 2.0) >= 1.0) {
outColor.b = outColor.b - (index * variation) / float(colorCount-1);
}
else {
outColor.b = outColor.b + (index * variation) / float(colorCount-1);
outColor.b = outColor.b - floor(outColor.b);
}
if (outColor.b < 0.075) {
outColor.b = 1.0 - outColor.b * variation;
}
if (mod(index, 3.0) >= 2.0) {
outColor.g = outColor.g - (index * variation) / 2.0;
}
else if (mod(index, 4.0) >= 3.0) {
outColor.g = outColor.g + (index * variation) / 2.0;
}
if ((outColor.g > 1.0) || (outColor.g < 0.05)) {
outColor.g = outColor.g - floor(outColor.g);
}
}
// Analogous small hue and saturation shifts
else if (colorMode == 5) {
outColor.r = outColor.r + variation * index * 1.0 / float(colorCount - 1);
if (mod(index, 3.0) >= 1.0) {
outColor.g = outColor.g - variation / 2.0;
if (outColor.g < 0.0) {
outColor.g = outColor.g + variation / 2.0;
}
if (outColor.g > 1.0) {
outColor.g = outColor.g - floor(outColor.g);
}
}
}
// Compound Analogous similar to analogous but with negative hue shifts
else if (colorMode == 6) {
if (mod(index, 3.0) >= 1.0) {
outColor.r = outColor.r + variation * index * 1.0 / float(colorCount - 1);
}
else {
outColor.r = outColor.r - variation * index * 0.5 / float(colorCount - 1);
}
if (mod(index, 3.0) >= 1.0) {
outColor.g = outColor.g - variation / 2.0;
if (outColor.g < 0.0) {
outColor.g = outColor.g + variation;
}
if (outColor.g > 1.0) {
outColor.g = outColor.g - floor(outColor.g);
}
}
if (mod(index, 4.0) >= 2.0) {
if (outColor.b < variation) {
outColor.b = outColor.b + variation;
}
}
}
gl_FragColor = vec4(hsv2rgb(outColor.rgb), inColor.a);
}
}